'use strict';
const { src, dest, parallel, series, watch } = require('gulp');
const path = require('path');

const usePlugins = require('gulp-load-plugins');
const plugins = usePlugins();

const del = require('del');
const browserSync = require('browser-sync');

const bs = browserSync.create();
// 获取当前路径
const cwd = process.cwd();
// 默认配置
let config = {
  build: {
    src: 'src',
    dist: 'release',
    temp: '.tmp',
    public: 'public',
    paths: {
      styles: 'assets/styles/*.scss',
      scripts: 'assets/scripts/*.js',
      pages: '*.html',
      images: 'assets/images/**',
      fonts: 'assets/fonts/**'
    }
  },
};

// 改成模块化导入
// 将工程化改为可配置
try{
  const loadConfig = require(path.join(cwd, 'page.config.js'));
  config = Object.assign({}, config, loadConfig);
}catch (e) {
  // err
}

// 清理任务
const clean = () => {
  return del([config.build.dist, config.build.temp]);
};

// 样式编译任务
const style = () => {
  return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }));
};

// js编译任务
const script = () => {
  return src(config.build.paths.scripts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.babel({ presets: [require('@babel/preset-env')] }))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }));
};

// html模板编译
const html = () => {
  return src(config.build.paths.pages, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.swig({ data: config.data , defaults: { cache: false }}))
    .pipe(dest(config.build.temp))
    .pipe(bs.reload({ stream: true }));
};

// 图片编译
const img = () => {
  return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
};

// 字体文件编译
const font = () => {
  return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist));
};

// 剩余文件编译
const extra = () => {
  return src('**', { base: config.build.public, cwd: config.build.public })
    .pipe(dest(config.build.dist));
};

// 引用替换 + 文件压缩
const useRef = () => {
  return src(config.build.paths.pages, { base: config.build.temp, cwd: config.build.temp })
    .pipe(plugins.useref({ searchPath: [config.build.temp, '.'] }))
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true,
    })))
    .pipe(dest(config.build.dist));
};

// 热更新服务器
const serve = () => {
  // 监听必须编译的文件
  watch(config.build.paths.styles, { cwd: config.build.src }, style);
  watch(config.build.paths.pages, { cwd: config.build.src }, html);
  watch(config.build.paths.scripts, { cwd: config.build.src }, script);

  // 监听不需要编译的文件，修改也刷新服务器
  watch([
    config.build.paths.images,
    config.build.paths.fonts,
  ], { cwd: config.build.src }, bs.reload);

  watch([
    '**'
  ], { cwd: config.build.public }, bs.reload);

  bs.init({
    notify: false,
    // files: 'temp/**',
    server: {
      baseDir: [config.build.temp, config.build.src, config.build.public],
      routes: {
        '/node_modules': 'node_modules',
      },
    },
  });
};

// 组合基础编译任务
const compile = parallel(html, style, script);

// 组合开发任务
const develop = series(compile, serve);

// 组合发布任务
const build = series(clean, parallel(series(compile, useRef), img, font, extra));

module.exports = {
  clean,
  develop,
  build
};
